package com.share.common.result;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.share.common.enums.HttpStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;

/**
 * 统一API响应结果封装
 *
 * @param <T> 数据类型
 * @author javadog
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    private Integer code;

    /**
     * 是否成功
     */
    private Boolean success;

    /**
     * 返回消息
     */
    private String msg;

    /**
     * 错误时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
    private Instant timestamp;

    /**
     * 返回数据
     */
    private T data;

    /**
     * 创建响应结果
     *
     * @param code    状态码
     * @param success 是否成功
     * @param msg     返回消息
     * @param data    返回数据
     * @param <T>     数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> of(Integer code, Boolean success, String msg, T data) {
        return new ResponseResult<>(code, success, msg, Instant.now(),data);
    }

    /**
     * 创建响应结果（无数据）
     *
     * @param code    状态码
     * @param success 是否成功
     * @param msg     返回消息
     * @param <T>     数据类型
     * @return 响应结果
     */
    private static <T> ResponseResult<T> of(Integer code, Boolean success, String msg) {
        return of(code, success, msg, null);
    }

    // 成功响应方法

    /**
     * 成功响应（默认状态码和消息）
     *
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success() {
        return of(HttpStatusEnum.SUCCESS.getCode(), true,
                HttpStatusEnum.SUCCESS.getMessage());
    }

    /**
     * 成功响应（带数据）
     *
     * @param data 返回数据
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success(T data) {
        return of(HttpStatusEnum.SUCCESS.getCode(), true, HttpStatusEnum.SUCCESS.getMessage(), data);
    }

    /**
     * 成功响应（自定义消息）
     *
     * @param msg 返回消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success(String msg) {
        return of(HttpStatusEnum.SUCCESS.getCode(), true, msg);
    }

    /**
     * 成功响应（自定义消息和数据）
     *
     * @param msg  返回消息
     * @param data 返回数据
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success(String msg, T data) {
        return of(HttpStatusEnum.SUCCESS.getCode(), true, msg, data);
    }

    /**
     * 成功响应（自定义状态码和消息）
     *
     * @param code 状态码
     * @param msg  返回消息
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success(Integer code, String msg) {
        return of(code, true, msg);
    }

    /**
     * 成功响应（自定义状态码、消息和数据）
     *
     * @param code 状态码
     * @param msg  返回消息
     * @param data 返回数据
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success(Integer code, String msg, T data) {
        return of(code, true, msg, data);
    }

    /**
     * 成功响应（使用枚举定义）
     *
     * @param statusEnum 状态枚举
     * @param <T>        数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> success(HttpStatusEnum statusEnum) {
        return of(statusEnum.getCode(), true, statusEnum.getMessage());
    }

    // 失败响应方法

    /**
     * 失败响应（默认状态码和消息）
     *
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail() {
        return of(HttpStatusEnum.INTERNAL_SERVER_ERROR.getCode(), false, HttpStatusEnum.INTERNAL_SERVER_ERROR.getMessage());
    }

    /**
     * 失败响应（默认状态码和消息）
     *
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail(T data) {
        return of(HttpStatusEnum.INTERNAL_SERVER_ERROR.getCode(),
                false, HttpStatusEnum.INTERNAL_SERVER_ERROR.getMessage(),data);
    }

    /**
     * 失败响应（自定义消息）
     *
     * @param msg 返回消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail(String msg) {
        return of(HttpStatusEnum.INTERNAL_SERVER_ERROR.getCode(), false, msg);
    }

    /**
     * 失败响应（自定义状态码和消息）
     *
     * @param code 状态码
     * @param msg  返回消息
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail(Integer code, String msg) {
        return of(code, false, msg);
    }

    /**
     * 失败响应（自定义消息和数据）
     *
     * @param msg  返回消息
     * @param data 返回数据
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail(String msg, T data) {
        return of(HttpStatusEnum.INTERNAL_SERVER_ERROR.getCode(), false, msg, data);
    }

    /**
     * 失败响应（自定义状态码、消息和数据）
     *
     * @param code 状态码
     * @param msg  返回消息
     * @param data 返回数据
     * @param <T>  数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail(Integer code, String msg, T data) {
        return of(code, false, msg, data);
    }

    /**
     * 失败响应（使用枚举定义）
     *
     * @param statusEnum 状态枚举
     * @param <T>        数据类型
     * @return 响应结果
     */
    public static <T> ResponseResult<T> fail(HttpStatusEnum statusEnum) {
        return of(statusEnum.getCode(), false, statusEnum.getMessage());
    }

    /**
     * 判断响应是否成功
     *
     * @return 是否成功
     */
    public boolean isSuccess() {
        return Boolean.TRUE.equals(success);
    }
}